package com.ycy.nio;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.*;
import java.nio.charset.CharsetDecoder;
import java.nio.charset.StandardCharsets;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.TimeUnit;

public class NewIO3 {

  public static final Logger logger = LoggerFactory.getLogger(NewIO3.class);

  public static void main(String[] args) {
    NewIO3 m = new NewIO3();
    m.doWork();
  }

  public void doWork() {
    try {

//      SocketChannel open = SocketChannel.open();

      ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
      serverSocketChannel.bind(new InetSocketAddress(8080));
      serverSocketChannel.configureBlocking(false);

      Selector selector = Selector.open();

      SelectionKey register = serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

      while (true) {
        try {
          TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
        //阻塞方法 有事件发生
        selector.select();
        Set<SelectionKey> selectionKeys = selector.selectedKeys();

        Iterator<SelectionKey> iterator = selectionKeys.iterator();
        while (iterator.hasNext()) {
          SelectionKey selectionKey = iterator.next();
          iterator.remove();
          if (selectionKey.isAcceptable()) {
            //链接事件
            handlerAccept(selector, selectionKey);
          } else if (selectionKey.isReadable()) {
            //读取事件
            handlerRead(selector, selectionKey);
          } else {
            logger.error(selectionKey.toString());
          }
        }

      }


    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder();

  private void handlerRead(Selector selector, SelectionKey selectionKey) {

    SelectableChannel channel = selectionKey.channel();
    SocketChannel socketChannel = (SocketChannel) channel;

    ByteBuffer allocate = ByteBuffer.allocate(1024);
    try {
      int read = socketChannel.read(allocate);
      if (read > 0) {
        allocate.flip();
        CharBuffer decode = decoder.decode(allocate);
        System.out.println("client : " + decode);

      }
      socketChannel.close();


    } catch (IOException e) {
      e.printStackTrace();
    }

  }

  private void handlerAccept(Selector selector, SelectionKey selectionKey) {

    SelectableChannel channel = selectionKey.channel();
    ServerSocketChannel socketChannel = (ServerSocketChannel) channel;
    try {
      SocketChannel client = socketChannel.accept();
      if (client == null) return;
      client.configureBlocking(false);
      client.register(selector, SelectionKey.OP_READ);
    } catch (IOException e) {
      e.printStackTrace();
    }

  }


}
